Categories
React

Framer Motion — Drag Animation

Spread the love

With the Framer Motion library, we can render animations in our React app easily.

In this article, we’ll take a look at how to get started with Framer Motion.

Drag and Layout Animations

We can animate our elements when we drag it.

For example, we can write:

import { motion } from "framer-motion";
import React from "react";

export default function App() {
  return (
    <motion.div
      style={{ backgroundColor: "red", width: 100, height: 100 }}
      drag="x"
      dragConstraints={{ left: 0, right: 300 }}
    />
  );
}

to add a div and then make it draggable.

We make it draggable by setting the drag prop to 'x' to let us drag horizontally.

The dragConstraints prop lets us set the limits of the dragging.

Also, we can set the drag limit to the bounds of another element.

For instance, we can write:

import { motion } from "framer-motion";
import React, { useRef } from "react";

export default function App() {
  const constraintsRef = useRef(null);

  return (
    <motion.div
      ref={constraintsRef}
      style={{ backgroundColor: "green", width: 200, height: 200 }}
    >
      <motion.div
        style={{ backgroundColor: "red", width: 100, height: 100 }}
        drag
        dragConstraints={constraintsRef}
      />
    </motion.div>
  );
}

to set the drag limit to the bound of the outer div.

We can also set the degree of movement allowed outside the constraints.

For example, we can write:

import { motion } from "framer-motion";
import React from "react";

export default function App() {
  return (
    <motion.div
      drag
      dragConstraints={{ left: 0, right: 300 }}
      dragElastic={0.2}
      style={{ backgroundColor: "red", width: 100, height: 100 }}
    />
  );
}

We set the dragElastic prop to set the amount of movement allowed outside the drag constraints.

The dragMomentum prop lets us apply momentum from the pan gesture of the component while dragging finishes.

It’s true by default.

We can use it by writing:

import { motion } from "framer-motion";
import React from "react";

export default function App() {
  return (
    <motion.div
      drag
      dragConstraints={{ left: 0, right: 300 }}
      dragMomentum={false}
      style={{ backgroundColor: "red", width: 100, height: 100 }}
    />
  );
}

to remove the extra movement after we finish dragging.

The dragPropagation prop lets us allow drag gestures to propagate to child components.

For example, we can write:

import { motion } from "framer-motion";
import React from "react";

export default function App() {
  return (
    <motion.div
      drag="x"
      style={{ backgroundColor: "red", width: 100, height: 100 }}
    >
      <motion.div
        drag="x"
        dragConstraints={{ left: 0, right: 300 }}
        dragPropagation
        style={{
          backgroundColor: "green",
          width: 50,
          height: 50
        }}
      ></motion.div>
    </motion.div>
  );
}

Then when we drag the child div, the parent div will also move.

We can control dragging with the useDragControls hook.

For example, we can write:

import { motion, useDragControls } from "framer-motion";
import React from "react";

export default function App() {
  const dragControls = useDragControls();

  function startDrag(event) {
    dragControls.start(event, { snapToCursor: true });
  }

  return (
    <>
      <div onPointerDown={startDrag}>click to drag</div>
      <motion.div
        style={{ backgroundColor: "red", width: 100, height: 100 }}
        drag="x"
        dragControls={dragControls}
      />
    </>
  );
}

We set the onPointerDown prop to the starDrag function.

startDrag calls the dragControls.start method to move the red div.

snapToCursor set to true means that the div will move to align to where the cursor is.

So when we click on the 'click to drag' text, the div will move toward the cursor.

Conclusion

We can animate when we drag an element with Framer Motion.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *